package com.qf.ssm.service.Impl;

import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.pagehelper.PageHelper;
import com.qf.ssm.dao.UserDao;
import com.qf.ssm.entity.User;
import com.qf.ssm.service.UserService;
import com.qf.ssm.vo.AddUserVo;
import com.qf.ssm.vo.ResultVo;
import com.qf.ssm.vo.SearchUserVo;
import com.qf.ssm.vo.UserVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.management.RuntimeErrorException;
import java.io.*;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author manchi520
 * @date 2022/7/5
 * @apiNote
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
    //上传头像的路径
    @Value("${fileDir}")
    private String filedir;
    //文件名分隔符
    @Value(("${separator}"))
    private String separator;
    //导出文件路径
    @Value("${exportDir}")
    private String exportdir;
    //上传文件的存储目录
    private String uploaddir;
    @Autowired
    private UserDao userDao;

    /**
     * 登录验证方法
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public User login(String username, String password) {
        return userDao.findByUsernameAndPassword(username, password);
    }

    /**
     * 用户注册方法
     *
     * @param userVo
     * @return
     */
    @Override
    public User register(UserVo userVo) {
        User user;
        try {
            User userDaoByName = userDao.findByName(userVo.getName());

            //1、处理文件路径
            //获取文件名
            String originalFilename = userVo.getFilepath().getOriginalFilename();
            //获取UUID前缀，并将格式中的"-"去掉
            String prefix = UUID.randomUUID().toString().replaceAll("-", "");
            //拼出最终文件名
            String finalFileName = prefix + separator + originalFilename;
            //拿到最终需要上传的文件路径
            String finalFilePath = filedir + finalFileName;
            //上传文件
            userVo.getFilepath().transferTo(new File(finalFilePath));
            log.debug("文件上传成功，路径为：{}", finalFilePath);

            //2、处理user对象数据
            user = new User();
            //将传过来的uservo对象的值赋给user对象中同属性
            BeanUtils.copyProperties(userVo, user);
            log.debug("正在给将传过来的uservo对象的值赋给user对象中同属性，uservo={},user={}", userVo, user);
            String pa = DigestUtil.md5Hex(userVo.getPassword());
            log.debug("开始给用户密码进行MD5加密，加密后的密码为：pa={}", pa);
            user.setFilepath(finalFilePath);
            user.setRegistTime(new Date());
            user.setPassword(pa);
            userDao.register(user);
            log.debug("用户注册成功，正在返回controller层.....");
            return user;

        } catch (IOException e) {
            e.printStackTrace();
            log.debug("用户注册失败，异常信息为：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 查询该用户是否注册过账号
     * @param userVo
     * @return
     */
    @Override
    public User nameRepeat(UserVo userVo) {
        return userDao.findByName(userVo.getName());
    }

    /**
     * 根据用户名查询用户
     * @param currentPage
     * @param pageSize
     * @param searchUserVo
     * @return
     */
    @Override
    public List<User> findByName(Integer currentPage, Integer pageSize, SearchUserVo searchUserVo) {
        PageHelper.startPage(currentPage,pageSize);
        List<User> userList = userDao.search(searchUserVo);
        return userList;
    }

    /**
     * 查找所有用户信息
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public List<User> findAll(Integer currentPage,Integer pageSize) {
        PageHelper.startPage(currentPage,pageSize);
        return userDao.findAll();
    }

    @Override
    public String exportAll(){
        //1. 查询所有用户数据
        final List<User> allUsers = userDao.findAll();

        //2. 将List写入文本文件
        final String prefix = UUID.randomUUID().toString().replaceAll("-", "");
        final String finalFileName = prefix + "t_users.csv";
        final String finalFilePath = exportdir + finalFileName;

        // hutool csv文件 writer对象
        CsvWriter writer = CsvUtil.getWriter(finalFilePath, CharsetUtil.CHARSET_UTF_8);
        writer.writeBeans(allUsers);
        writer.close();
        return finalFileName;
    }

    /**
     * 根据id批量删除
     * @param ids
     * @return
     */
    @Override
    public int deleteById(int[] ids) {
        return userDao.deleteById(ids);
    }

    /**
     * 添加用户
     * @param addUserVo
     * @return
     */
    @Override
    public int addUser(AddUserVo addUserVo) {
        User user = new User();
        BeanUtils.copyProperties(addUserVo,user);
        return userDao.addUser(user);
    }

    /**
     * 更新编辑用户
     * @param user
     * @return
     */
    @Override
    public int updateUser(User user) {
        return userDao.updateUser(user);
    }

    /*@Override
    public String findPicPath(Integer id) {
        //根据id查询出该用户的所有信息
        User user = userDao.findById(id);
        //返回用户的头像路径
        return user.getFilepath();
    }*/

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer uploadUser(MultipartFile file) throws IOException {

        // 1. 把file保存成 csv文件
        final String prefix = UUID.randomUUID().toString().replaceAll("-", "");
        final String finalFileName = prefix + "t_users.csv";
        final String finalFilePath = uploaddir + finalFileName;

        file.transferTo(new File(finalFilePath));

        // 2. 读取 csv文件中的内容， 转换成 List<User>
        final CsvReader reader = CsvUtil.getReader();
        final List<User> userList = reader.read(new FileReader(finalFilePath), User.class);

        // 3. 去重
        // 3.1 把user表中现有的所有user数据查询出来
        final List<User> existUserList = userDao.findAll();

        // 转换： List<User> ----->  List<String> ,String 代表用户名
        final List<String> usernNameList = existUserList.stream().map(user -> user.getName()).collect(Collectors.toList());

        // 3.2 过滤 userList
        final List<User> reaminList = userList.stream().filter(user -> {

            final String name = user.getName();
            // 判断name是否在usernNameList中存在，如果存在的话，则返回false，过滤调当前user
            return !usernNameList.contains(name);

        }).collect(Collectors.toList());

        // 3.3 对于reaminList中的明文的密码需要进行md5处理


        // 4. 批量插入数据库
        if (reaminList.size()>0){
            Integer lines =  userDao.batchInsertUser(reaminList);
            return lines;
        }

        return 0;
    }
}
